package parse_omim_txt;

require Exporter;


our @ISA = qw(Exporter);
our $VERSION = 1.00;
our @EXPORT = qw(parse_records);

use strict;
use warnings;

#_________________________________________________________________________________________

#	parse_records

#		Input:

#			$fh
#				reads sequence from <fh>

#			@fields to pass to the callback

#			$callback($$$$)
#				function to call with sequence and annotation info
#					takes 4 parameters:

#						$saved_fields	hash of array of saved lines
#										e.g. $saved_fields->{'SQ'}[0] = "ASDFASDFG"
# 						$recstart		the file position of the record
# 						$reccnt 		the count of parsed records
#						$data			see below

#			$data				called as $callback parameter
#									so that data can be stored if necessary

#_________________________________________________________________________________________
sub parse_records(*\@&$)
{
	my ($fh, $FIELDS_TO_SAVE, $callback, $data) = @_;

	my %FIELDS_TO_SAVE;
	@FIELDS_TO_SAVE{@$FIELDS_TO_SAVE} = ();
	my %saved_fields;
	my $reccnt			= 0;
	my $linecnt			= 0;
	my $rec_filepos		= 0;
	my $rec_line		= 1;
	my $curr_file_pos	= 0;
	my $curr_field		= undef;
	while(<$fh>)
	{
		++$linecnt;
		
		chomp;

		#skip empty lines
#		next if $_ eq '';

		#
		# End Of File
		#
		#		 should only occur after a record
		#
		if (/^\*THEEND\*/ && defined $curr_field)
		{
			$callback-> (	\%saved_fields,		 	# accession
							$rec_filepos,			# the file position of the record
							$rec_line,				# the line the record starts on
							++$reccnt, 				# the count of parsed records
							$data					# user call back
						);
			return $reccnt;
		}
		

		#
		# Send parsed record to call back
		#
		#		 before the start of the next record
		#
		if (/^\*RECORD\*/)
		{
			if ($reccnt++)
			{
				# send the record just parsed to the callback function
				# if callback returns true, terminate process prematurely
				if ($callback->(	\%saved_fields,		 	# accession
									$rec_filepos,			# the file position of the record
									$rec_line,				# the line the record starts on
									$reccnt, 				# the count of parsed records
									$data					# user call back
								))
				{
					return $reccnt;
				}
			}
			%saved_fields = ();
			$curr_field = undef;
			$rec_filepos = $curr_file_pos;
			$rec_line	 = $linecnt;
			next;
		}
		
		# save file position
		$curr_file_pos = tell();
		
		
		
		#
		# field type change
		#
		if (/^\*FIELD\*\s+([A-Z]+)/)
		{
			$curr_field = $1;
			next;
		}
		
		#
		# make sure actually inside some field
		#
		die "Fatal Error:\n\t".
			"Text outside field in Record # $reccnt on line $.\n\t[$_]\n"
			if ($curr_field eq '');
		
		#
		# ignore text if current field not of interest
		#
		next unless (exists $FIELDS_TO_SAVE{$curr_field});
			
		#
		# save text in field
		#
		push(@{$saved_fields{$curr_field}}, $_);
	}

	die "Fatal Error:\n\t".
		"Ended prematurely in Record # $reccnt on line $.\n\t[$_]\n\t".
	    'The file should end with "*THEEND*"\n';

	return $reccnt;
}







